package com.crm.crm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crm.crm.constant.CacheConstant;
import com.crm.crm.domain.*;

import com.crm.crm.domain.dto.business.*;
import com.crm.crm.domain.vo.PageResult;
import com.crm.crm.domain.vo.business.BusinessVo;
import com.crm.crm.domain.dto.business.NewBusinessDto;
import com.crm.crm.mapper.*;
import com.crm.crm.service.BusinessService;
import com.crm.crm.util.UserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class BusinessServicelmpl extends ServiceImpl<BusinessMapper, BusinessOpportunity> implements BusinessService {
    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    private DeptServicelmpl deptServicelmpl;

    @Autowired
    private BusinessPoolMapper businessPoolMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RulePoolMapper rulePoolMapper;

    @Autowired
    private BusinessRecordMapper businessRecordMapper;
    @Autowired
    private IndexMapper indexMapper;


    //    分页查询
    @Override
    public Page<BusinessOpportunity> list(BusinessListDto queryDTO, Page<BusinessOpportunity> page) {
        LambdaQueryWrapper<BusinessOpportunity> wrapper = new LambdaQueryWrapper<>();

        // 根据起始时间查询。判断是否有内容，没有则查询所有
        // 根据起始时间查询。判断是否有内容，没有则查询所有
        // 时间范围查询
        if (StringUtils.isNotEmpty(queryDTO.getBeginCreateTime())) {
            wrapper.ge(BusinessOpportunity::getCreateTime, queryDTO.getBeginCreateTime());
        }
        if (StringUtils.isNotEmpty(queryDTO.getEndCreateTime())) {
            wrapper.le(BusinessOpportunity::getCreateTime, queryDTO.getEndCreateTime() + " 23:59:59");
        }//        id模糊查询
        if (queryDTO.getId() != null) {
            wrapper.like(StringUtils.isNotEmpty(queryDTO.getId().toString()), BusinessOpportunity::getId, queryDTO.getId());
        }
//        电话号码，模糊查询
        wrapper.like(StringUtils.isNotEmpty(queryDTO.getName()), BusinessOpportunity::getName, queryDTO.getName());
//        归属人，模糊查询
        wrapper.like(StringUtils.isNotEmpty(queryDTO.getOwner()), BusinessOpportunity::getOwner, queryDTO.getOwner());
//        跟进状态，模糊查询
        wrapper.like(StringUtils.isNotEmpty(queryDTO.getStatus()), BusinessOpportunity::getStatus, queryDTO.getStatus());
        // 使用 MyBatis Plus 分页查询
        return businessMapper.selectPage(page, wrapper);
    }

    //根据ID修改归属人
    @Override
    public Integer updateById(BusinessBatchDTO dto) {

        // 根据员工ID查询员工信息,作为归属人
        String owner = deptServicelmpl.getOwner(dto.getUserId());
        log.info("修改归属人账户名：{}", owner);
        List<Integer> ids = dto.getIds();

        //判断分配后用户持有总数是否会大于最大可持有数
        Integer maxNumber = getMaxNumber();
        //判断加上size，用户总持有数是否大于最大可持有数
        LambdaQueryWrapper<BusinessOpportunity> userWrapper = new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getOwner, owner);
        List<BusinessOpportunity> businessOpportunities = businessMapper.selectList(userWrapper);
        if (businessOpportunities.size() + ids.size() > maxNumber) {
            //throw new RuntimeException("捞取线索不能超过" + maxNumber + "条");
            return 4;
        }

//        将员工信息修改到商机数据库中
//        因为要求最多选择两条商机，所以最多执行两次数据库操作，使用for循环
        if (ids.size() > 2) {
            return 3;
        }
        int count = 0;
        //判断修改位置是不是在公海
        LambdaQueryWrapper<BusinessOpportunity> wrapper = new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getId, ids.get(0));
        List<BusinessOpportunity> businessOpportunitiesSize = businessMapper.selectList(wrapper);
        if (businessOpportunitiesSize.size() > 0) {
            //for循环遍历dto.getIds()
            for (Integer id : ids) {
                businessMapper.updateOwner(owner, id);
                count++;
            }
            return count;
        } else {
            String gain = gain(dto);
            if (gain == null) {
                return 1;
            } else {
                return 0;
            }
        }
    }


    /**
     * 根据id查询客户资料详情
     *
     * @param id
     * @return
     */
    @Override
    public BusinessVo getBusinessDetailsById(Long id) {
        LambdaQueryWrapper<BusinessOpportunity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BusinessOpportunity::getId, id);
        log.info("id为{}", id);
        BusinessOpportunity businessDetails = businessMapper.selectOne(wrapper);
        log.info("查询到的商机详情为{}", businessDetails);
        businessDetails.setNextTime(null);
        log.info("查询到的商机详情为{}", businessDetails);
        BusinessVo businessDetailsVo = new BusinessVo();
        BeanUtils.copyProperties(businessDetails, businessDetailsVo);
        return businessDetailsVo;
    }

    /**
     * 历史沟通记录列表查询
     *
     * @param businessId
     * @return
     */
    @Override
    public List<BusinessRecord> getBusinessRecordListById(Integer businessId) {
        LambdaQueryWrapper<BusinessRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BusinessRecord::getBusinessId, businessId);
        List<BusinessRecord> recordList = businessRecordMapper.selectList(wrapper);
        return recordList;
    }

    /**
     * 获取最大可持有数
     *
     * @return
     */
    public Integer getMaxNumber() {
        LambdaQueryWrapper<RulePool> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RulePool::getType, "1");
        RulePool rulePool = rulePoolMapper.selectOne(wrapper);
        return rulePool.getMaxNunmber();
    }

    /**
     * 新增商机
     *
     * @param newBusinessDto
     */
    @Override
    public String add(NewBusinessDto newBusinessDto) {
        String currentUserName = UserThreadLocalUtil.getCurrentUserName();
        //判断当前用户持有数是否超过最大可持有数
        Integer maxNunmber = getMaxNumber();

        LambdaQueryWrapper<BusinessOpportunity> userWrapper = new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getOwner, currentUserName);
        List<BusinessOpportunity> businessOpportunities = businessMapper.selectList(userWrapper);
        if (businessOpportunities.size() < maxNunmber) {
            BusinessOpportunity businessOpportunity = new BusinessOpportunity();
            BeanUtils.copyProperties(newBusinessDto, businessOpportunity);
            //System.out.println(businessOpportunity);
            businessOpportunity.setCreateBy(currentUserName);
            businessOpportunity.setOwner(currentUserName);
            businessMapper.insert(businessOpportunity);
            //新增记录
            String createBy = businessOpportunity.getCreateBy();
            LambdaQueryWrapper<InsertRecord> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(BeanUtil.isNotEmpty(createBy), InsertRecord::getCreateBy, createBy);
            InsertRecord insertRecord = indexMapper.selectOne(wrapper);
            if (insertRecord == null) {
                InsertRecord insertRecordNew = new InsertRecord();
                BeanUtil.copyProperties(businessOpportunity, insertRecordNew);
                insertRecordNew.setClueCount(0); // 设置线索增加数
                insertRecordNew.setClueChangeCount(0); // 设置线索转化数
                insertRecordNew.setBusinessCount(1); // 设置商机增加数
                insertRecordNew.setBusinessChangeCount(0); // 设置商机转化数
                indexMapper.insert(insertRecordNew);
            } else {
                insertRecord.setBusinessCount(insertRecord.getBusinessCount() + 1);
            }
            return null;
        } else {
            //超过持有最大数量
            return "当前用户线索数已满";
        }
    }


    /**
     * 修改商机信息并保存沟通记录
     *
     * @param businessMessageDto
     */
    @Override
    public void addAndUpdateBusiness(BusinessMessageDto businessMessageDto) {
        //客户信息以及意向
//        LambdaQueryWrapper<BusinessOpportunity> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(BusinessOpportunity::getPhone, businessMessageDto.getPhone());
//        wrapper.eq(BusinessOpportunity::getSubject, businessMessageDto.getSubject());
//        wrapper.eq(BusinessOpportunity::getWeixin, businessMessageDto.getWeixin());
//        wrapper.eq(BusinessOpportunity::getQq, businessMessageDto.getQq());
//        wrapper.eq(BusinessOpportunity::getAge, businessMessageDto.getAge());
//        wrapper.eq(BusinessOpportunity::getSex, businessMessageDto.getSex());
//        wrapper.eq(BusinessOpportunity::getName, businessMessageDto.getName());
//        wrapper.eq(BusinessOpportunity::getCreateBy, businessMessageDto.getCreateBy());
//        wrapper.eq(BusinessOpportunity::getCreateTime, businessMessageDto.getCreateTime());
//        wrapper.eq(BusinessOpportunity::getId, businessMessageDto.getId());
//        wrapper.eq(BusinessOpportunity::getNextTime, businessMessageDto.getNextTime());
//        wrapper.eq(BusinessOpportunity::getUpdateBy, businessMessageDto.getUpdateBy());
//        wrapper.eq(BusinessOpportunity::getUpdateTime, businessMessageDto.getUpdateTime());
//        log.info("商机信息：{}", wrapper);
        //客户信息、客户意向
        BusinessOpportunity businessOpportunity = new BusinessOpportunity();
        BeanUtils.copyProperties(businessMessageDto, businessOpportunity);
        businessOpportunity.setRegion(businessMessageDto.getRegion());
        businessOpportunity.setProvinces(businessMessageDto.getProvinces());
        businessOpportunity.setCity(businessMessageDto.getCity());
        businessOpportunity.setSubject(businessMessageDto.getSubject());
        businessOpportunity.setReason(businessMessageDto.getReason());
        businessOpportunity.setNextTime(LocalDateTime.parse(businessMessageDto.getNextTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        log.info("商机信息：{}", businessOpportunity);
        businessMapper.update(businessOpportunity, new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getPhone, businessMessageDto.getPhone()));

        log.info("businessOpportunity: {}", businessOpportunity);

//        businessMapper.update(businessOpportunity, wrapper);
        this.update(businessOpportunity, Wrappers.<BusinessOpportunity>lambdaUpdate().eq(BusinessOpportunity::getId, businessMessageDto.getBusinessId()));
        //沟通记录
        BusinessRecord businessRecord = new BusinessRecord();
        BeanUtils.copyProperties(businessMessageDto, businessRecord);
        businessRecord.setBusinessId(businessMessageDto.getBusinessId());
        businessRecord.setCreateTime(LocalDateTime.now());
        businessRecord.setCreateBy(businessMessageDto.getCreateBy());
        businessRecord.setKeyItems(businessMessageDto.getKeyItems());
//        businessRecord.setCreateBy(businessMessageDto.getCreateBy());
        businessRecord.setCreateBy(UserThreadLocalUtil.getCurrentUserName());
        businessRecord.setKeys(businessMessageDto.getKeys());
        businessRecord.setBusinessId(businessMessageDto.getBusinessId());
        businessRecord.setNextTime(LocalDateTime.parse(businessMessageDto.getNextTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        log.info("沟通记录为{}", businessRecord);

        businessRecordMapper.insert(businessRecord);
    }

    /**
     * 删除商机
     *
     * @param id
     */
    @Override
    public void deleteBusiness(Long id) {
        businessMapper.deleteById(id);
    }

    /**
     * 踢回公海
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean back(Long id, String reasonReporting) {
        //数据copy
        BusinessOpportunity businessOpportunity = businessMapper.selectById(id);
        BusinessPool businessPool = new BusinessPool();
        BeanUtils.copyProperties(businessOpportunity, businessPool);
        businessPool.setReasonReporting(reasonReporting);
        businessPool.setCreateTime(LocalDateTime.now());

        try {
            //删除商机表数据
            businessMapper.deleteById(id);
            //在商机公海中添加数据
            businessPoolMapper.insert(businessPool);
        } catch (Exception e) {
            log.info("踢回公海失败：{}", e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 商机公海列表查询
     *
     * @param businessPoolDto
     * @return
     */
    @Override
    public PageResult<BusinessPool> getPage(BusinessPoolDto businessPoolDto) {
        Page<BusinessPool> page = new Page<>(businessPoolDto.getPageNum(), businessPoolDto.getPageSize());
        LambdaQueryWrapper<BusinessPool> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(businessPoolDto.getId()), BusinessPool::getId, businessPoolDto.getId())
                .like(StringUtils.isNotEmpty(businessPoolDto.getName()), BusinessPool::getName, businessPoolDto.getName())
                .like(StringUtils.isNotEmpty(businessPoolDto.getPhone()), BusinessPool::getPhone, businessPoolDto.getPhone())
                .eq(StringUtils.isNotEmpty(businessPoolDto.getSubject()), BusinessPool::getSubject, businessPoolDto.getSubject());

        Map<String, String> params = businessPoolDto.getParams();
        String beginCreateTime = params.get("beginCreateTime");
        String endCreateTime = params.get("endCreateTime");
        LocalDate beginTimeDate = null;
        LocalDate endTimeDate = null;
        if (StrUtil.isNotEmpty(beginCreateTime) && StrUtil.isNotEmpty(endCreateTime)) {
            beginTimeDate = LocalDate.parse(beginCreateTime);
            endTimeDate = LocalDate.parse(endCreateTime);
        }
        wrapper.between(StrUtil.isNotEmpty(beginCreateTime) && StrUtil.isNotEmpty(endCreateTime), BusinessPool::getCreateTime, beginTimeDate, endTimeDate);

        Page<BusinessPool> pageResult = businessPoolMapper.selectPage(page, wrapper);
        return new PageResult<>(pageResult.getTotal(), pageResult.getRecords());
    }

    /**
     * 转出公海
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public String gain(BusinessBatchDTO dto) {
        List<Integer> ids = dto.getIds();
        if (ids.size() > 3) {
            //throw new RuntimeException("捞取线索不能超过3条");
            return "捞取线索不能超过3条";
        }

        Integer maxNumber = getMaxNumber();
        String currentUserName = UserThreadLocalUtil.getCurrentUserName();
        //判断加上size，用户总持有数是否大于最大可持有数
        LambdaQueryWrapper<BusinessOpportunity> userWrapper = new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getOwner, currentUserName);
        List<BusinessOpportunity> businessOpportunities = businessMapper.selectList(userWrapper);
        if (businessOpportunities.size() + ids.size() > maxNumber) {
            //throw new RuntimeException("捞取线索不能超过" + maxNumber + "条");
            return "捞取后当前用户持有总数会大于最大可持有数";
        }

        long userId = dto.getUserId();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, userId);
        String userName = userMapper.selectOne(wrapper).getUserName();

        //redis查一下看看是否存在重复捞取限制的
        for (Integer id : ids) {
            String string = redisTemplate.opsForValue().get(CacheConstant.RECYCLE_LIMIT_BUSINESS + id);
            if (string != null) {
                //throw new RuntimeException("存在处于重复捞取时限内的数据");
                return "存在处于重复捞取时限内的数据";
            }
        }

        ArrayList<BusinessOpportunity> businessOpportunitiesInsert = new ArrayList<>();
        ids.forEach(id -> {
            BusinessPool businessPool = businessPoolMapper.selectById(id);
            BusinessOpportunity businessOpportunity = new BusinessOpportunity();
            BeanUtils.copyProperties(businessPool, businessOpportunity);
            businessOpportunity.setOwner(userName);
            businessOpportunitiesInsert.add(businessOpportunity);
            addRecycleLimit(id);
        });

        try {
            businessPoolMapper.deleteByIds(ids);
            businessMapper.insert(businessOpportunitiesInsert);
        } catch (Exception e) {
            log.info("转出公海失败：{}", e.getMessage());
            return "\"转出公海失败：" + e.getMessage();
        }
        return null;
    }

    @Override
    public List getRecordList(Integer id) {
        List<BusinessRecord> list = businessRecordMapper.selectList(new LambdaQueryWrapper<BusinessRecord>().eq(BusinessRecord::getBusinessId, id));
        return list;
    }

    /*添加重复捞取限制方法*/
    private void addRecycleLimit(Integer id) {
        //拿限制时间与格式
        LambdaQueryWrapper<RulePool> wrapper = new LambdaQueryWrapper<RulePool>().eq(RulePool::getType, "1");
        RulePool rulePool = rulePoolMapper.selectOne(wrapper);
        Integer repeatGetTime = rulePool.getRepeatGetTime();
        String repeatType = rulePool.getRepeatType();
        switch (repeatType) {
            case "1":
                //时间类型为天
                redisTemplate.opsForValue().set(CacheConstant.RECYCLE_LIMIT_BUSINESS + id, "1", repeatGetTime, TimeUnit.DAYS);
                break;
            case "2":
                //时间类型为周
                redisTemplate.opsForValue().set(CacheConstant.RECYCLE_LIMIT_BUSINESS + id, "1", (repeatGetTime * 7), TimeUnit.DAYS);
                break;
            case "3":
                //时间类型为月
                redisTemplate.opsForValue().set(CacheConstant.RECYCLE_LIMIT_BUSINESS + id, "1", (repeatGetTime * 30), TimeUnit.DAYS);
                break;
            default:
                log.info("时间类型错误,请检查数据库或数据字典");
        }
    }

    //    id查询商机信息
    public BusinessOpportunity selectById(Integer id) {
        return businessMapper.selectById(id);
    }
}
